type RGB = [number, number, number]
type HexColor = `#${string}`

/**
 * HEX color to RGB color conversion
 * @param hex - HEX color string (e.g., "#FFFFFF" or "FFFFFF")
 * @returns RGB color as [number, number, number] or shows warning if invalid
 */
export function hexToRgb(hex: string): RGB | void {
  const reg = /^#?[0-9A-Fa-f]{6}$/
  if (!reg.test(hex)) {
    ElMessage.warning('输入错误的hex')
    return
  }

  const hexWithoutHash = hex.replace('#', '')
  const hexValues = hexWithoutHash.match(/../g)

  if (!hexValues || hexValues.length !== 3) {
    ElMessage.warning('输入错误的hex')
    return
  }

  return [parseInt(hexValues[0], 16), parseInt(hexValues[1], 16), parseInt(hexValues[2], 16)]
}

/**
 * RGB color to HEX color conversion
 * @param r - Red value (0-255)
 * @param g - Green value (0-255)
 * @param b - Blue value (0-255)
 * @returns HEX color string or shows warning if invalid
 */
export function rgbToHex(r: number, g: number, b: number): HexColor | void {
  const isValid = (value: number): boolean => Number.isInteger(value) && value >= 0 && value <= 255

  if (!isValid(r) || !isValid(g) || !isValid(b)) {
    ElMessage.warning('输入错误的rgb颜色值')
    return
  }

  const toHex = (value: number): string => {
    const hex = value.toString(16)
    return hex.length === 1 ? `0${hex}` : hex
  }

  return `#${toHex(r)}${toHex(g)}${toHex(b)}`
}

/**
 * Darken a color
 * @param color - HEX color string
 * @param level - Darkening level (0-1)
 * @returns Darkened HEX color or shows warning if invalid
 */
export function getDarkColor(color: string, level: number): HexColor | void {
  const reg = /^#?[0-9A-Fa-f]{6}$/
  if (!reg.test(color)) {
    ElMessage.warning('输入错误的hex颜色值')
    return
  }

  if (level < 0 || level > 1) {
    ElMessage.warning('level参数必须在0-1之间')
    return
  }

  const rgb = hexToRgb(color)
  if (!rgb) return

  const darkenedRgb = rgb.map((value) => Math.floor(value * (1 - level))) as RGB
  return rgbToHex(...darkenedRgb)
}

/**
 * Lighten a color
 * @param color - HEX color string
 * @param level - Lightening level (0-1)
 * @returns Lightened HEX color or shows warning if invalid
 */
export function getLightColor(color: string, level: number): HexColor | void {
  const reg = /^#?[0-9A-Fa-f]{6}$/
  if (!reg.test(color)) {
    ElMessage.warning('输入错误的hex颜色值')
    return
  }

  if (level < 0 || level > 1) {
    ElMessage.warning('level参数必须在0-1之间')
    return
  }

  const rgb = hexToRgb(color)
  if (!rgb) return

  const lightenedRgb = rgb.map((value) => Math.floor((255 - value) * level + value)) as RGB
  return rgbToHex(...lightenedRgb)
}
